/*
 * can_task.cpp
 *
 *  Created on: 2018-4-9
 *      Author: root
 */

#include <stddef.h>
#include <sys/socket.h>
#include <linux/can.h>
#include "app_debug_main.h"
#include "sys.h"
#include "program.h"
#include "tcu_can.h"
#include "can_task.h"
#include <sys/msg.h>
#include "protocol_can.h"
#include "com_include.h"
#include "Task_Timer.h"
#include "log_main.h"
#include "sys.h"
#include <pthread.h>
TTaskInfo Info_TaskTcuRecv[2];
int socket_can[]={-1,-1};
 pthread_mutex_t canSendMutex[2];//是否是这里出了问题通过主控发送到控制器
 /*******************************************************************************
  * Function Name  : os_mutex_lock
  * Description    : 互斥信号量上锁
  * Input          : mutex 要上锁的信号量   timeout 上锁超时   perr 返回状态
  * Output         : perr 返回状态
  * Return         : None
  *******************************************************************************/
// static u8 os_mutex_lock(pthread_mutex_t* pmutex)
// {
//     int re = 0;
//
//     ASSERT(pmutex != NULL);
//
//     if((re = pthread_mutex_lock(pmutex)) != 0)
//     {
//         printf("Mutex Lock Fail!! errno %d\n", re);
//     }
//
//     return re;
// }
 /*******************************************************************************
  * Function Name  : os_mutex_lock
  * Description    : 互斥信号量解锁
  * Input          : mutex 要解锁的信号量
  * Output         : None
  * Return         : u8 解锁状态
  *******************************************************************************/
// static u8 os_mutex_unlock(pthread_mutex_t* pmutex)
// {
//     int re = 0;
//
//     ASSERT(pmutex != NULL);
//
//     if((re = pthread_mutex_unlock(pmutex)) != 0)
//     {
//         printf("Mutex unLock Fail!! errno %d\n",re);
//     }
//
//     return re;
// }


u16 Count2CS(u8* pData,u16 usLen)///111222333
{
    u16 cs = 0;
    u16 i=0;
    for(i=0; i < usLen; i++)
    {
       cs += pData[i];
    }
    return cs;
}
int TcuSendToCha(u8 port,GW_Can *gwcan) {
	Msg_J1939 msg;
	u16 cs=0;
	u32 ExtId;
	CanMsg txmsg;
	char temp_str[64];
	int num1,num2;
	int ret, i;

//	u8 flag_first[]={1,1};
//
//    if(flag_first[0]==1)
//    {
//    	if(pthread_mutex_init(&canSendMutex[0], NULL) ==0)
//    	{
//    		flag_first[0]=0;
//       	}
//
//    }
//    if(flag_first[1]==1)
//    {
//    	if(pthread_mutex_init(&canSendMutex[1], NULL) ==0)
//    	{
//    		flag_first[1]=0;
//       	}
//
//    }
//    if(gwcan->pf==7)
//    	   printf("888888888888888888888   %s\r\n",(char*)"TcuSendToCha");
//    	 DEBUG_SHOW1("收到的dllCan要求发送的数据包 pf=%x   %.*a",gwcan->pf,gwcan->lendata,gwcan->pdata);
	if (socket_can[port] == -1)
	{
		printf("初始化未完成！！！！！！！！！！！！！！！\n");
		return -2;
	}
	msg.pdata = gwcan->pdata;
	msg.pf = gwcan->pf;
	msg.ps = gwcan->ps;
	msg.sa = gwcan->sa;
	msg.priority = gwcan->priority;
	msg.R = 0;
	msg.DP = 0;
	msg.lendata = gwcan->lendata;
	ExtId = (msg.priority << 26) | (msg.R << 25) | (msg.DP << 24)
			| (msg.pf << 16) | msg.ps << 8 | (msg.sa);
	txmsg.can_id = ExtId;


	if (msg.lendata <= 8) {
		txmsg.can_dlc = msg.lendata;
		memcpy(txmsg.data, msg.pdata, txmsg.can_dlc);
		can_debug1("port=%d  向控制器发送TCU ID：%8x",port, txmsg.can_id);
		can_debug1("数据=%.*a", txmsg.can_dlc, txmsg.data);
	 //  fs_debug(CAN,"发送 %8x  %.*a", txmsg.can_id,txmsg.can_dlc, txmsg.data);

		sprintf(temp_str, "发送 %8x  %2x %2x %2x %2x %2x %2x %2x %2x\n", txmsg.can_id,txmsg.data[0], txmsg.data[1], txmsg.data[2], txmsg.data[3] , txmsg.data[4], txmsg.data[5], txmsg.data[6], txmsg.data[7]);
		if(port==0)
			fs_debugcan0(CAN,SEND,temp_str);// txmsg.can_id
		else if(port==1)
			fs_debugcan1(CAN,SEND,temp_str);// txmsg.can_id
		txmsg.can_id |= CAN_EFF_FLAG;
         ret=-1;

//         if(txmsg.data[0]==0)
//         {
//        	 while(1)
//        	 {
//        		 printf("send err err ");
//        	 }
//         }
	//	  os_mutex_lock(&canSendMutex[port]);
		ret = write(socket_can[port], &txmsg, sizeof(txmsg));
	//     os_mutex_unlock(&canSendMutex[port]);
		if (ret < 0)
		{
		//	g_uidata->can_state[port]=1;
		    printf("\r\n\r\n\r\ncan 发送失败(%d)!!!!!!!!!port=%d\r\n", ret, port);
		}

		else
			printf("\r\n\r\n\r\ncan 发送成功!!!!!!!!! port=%d\r\n",port);
	} else {

		u8 temp[32];
		u16 len;
		can_debug1("多帧数据长度  len=%d",msg.lendata);
        len=msg.lendata+5;
		num1=len/7;
		num2=len%7;
		if(num2!=0)
			num1++;
	    temp[0]=num1;
		temp[1]=msg.lendata%256;
		temp[2]=msg.lendata/256;
		memcpy(&temp[3], msg.pdata,msg.lendata);
		cs = Count2CS(temp, len-2);
		can_debug1("多帧数据长度  len=%d cs=%x  cs=%x",msg.lendata,cs%256,cs/256);while(1)
		temp[len - 2] = cs % 256;
		temp[len - 1] = cs / 256;
		if (num2 != 0)
			memset(&temp[len], 0, 7 - num2);
	//	 os_mutex_lock(&canSendMutex[port]);
		for (i = 0; i < num1; i++) {
			txmsg.can_dlc = 8;
			txmsg.can_id = ExtId;
			txmsg.data[0]=i+1;
			memcpy(&txmsg.data[1], &temp[i * 7], 7);
//			can_debug("控制器多帧返回TCU ID：%8x i=%d", txmsg.can_id, i);
//			can_debug("数据=%.*a", txmsg.can_dlc, txmsg.data);
//			sprintf(temp_str, "发送 %8x  %2x %2x %2x %2x %2x %2x %2x %2x\n", txmsg.can_id,txmsg.data[0], txmsg.data[1], txmsg.data[2], txmsg.data[3] , txmsg.data[4], txmsg.data[5], txmsg.data[6], txmsg.data[7]);
//			if(port==0)
//				fs_debugcan0(CAN,SEND,temp_str);// txmsg.can_id
//			else if(port==1)
//				fs_debugcan1(CAN,SEND,temp_str);// txmsg.can_id

//			print_frame(&txmsg);
			txmsg.can_id |= CAN_EFF_FLAG;

			ret = write(socket_can[port], &txmsg, sizeof(txmsg));

		}
	 //    os_mutex_unlock(&canSendMutex[port]);
	}
	return 0;
}

int findexistaddr(u8 port,u8 addr)
{
	canlink *p = g_pcan[port];
	if (p == NULL)
	{
		return -1;
	}

	do
	{
		if(addr==p->addr)
		{
			return p->qid;
		}
        p=p->pNext;
	}while(p!=NULL);
	return -2;
}
//int findexistaddr(u8 port,u8 addr,canxxx *ptail)
//{
//	canxxx *p=g_pcan[port];
//	int qid=-1;
//	ptail=p;
//
//	if(p==NULL)
//		return -1;
//	do
//	{
//		ptail=p;
//		if(addr==p->addr)
//		{
//			qid=p->qid;
//		}
//       p=p->pNext;
//	}while(p->pNext!=NULL);
//	return qid;
//}

int analyseCan(u8 port,CanMsg *pRxmsg,GW_Can &gwcan)
{
	u32 ExtId;
	int qid=0;
	char temp_str[64];
	if (pRxmsg->can_id & CAN_ERR_FLAG) {/* 出错设备错误 */
		handle_err_frame(pRxmsg);
		myerr("\r\n\r\nCAN device error\r\n");
		return -1;
	}

	sprintf(temp_str, "接收 %8x  %2x %2x %2x %2x %2x %2x %2x %2x\n", pRxmsg->can_id,pRxmsg->data[0], pRxmsg->data[1], pRxmsg->data[2],
			pRxmsg->data[3] , pRxmsg->data[4], pRxmsg->data[5], pRxmsg->data[6], pRxmsg->data[7]);

	if(port==0)
	{
       fs_debugcan0(CAN,RECV,temp_str);// txmsg.can_id
	}
	else if(port==1)
	{
		 fs_debugcan1(CAN,RECV,temp_str);// txmsg.can_id
	}
	ExtId = CAN_EFF_MASK & pRxmsg->can_id;


	gwcan.priority = ExtId >> 26;
	gwcan.pf = ExtId >> 16;
	gwcan.ps = ExtId >> 8;
	gwcan.sa = ExtId;
	gwcan.lendata=pRxmsg->can_dlc;

	if (gwcan.ps != TCU_CAN_ADDR )
	{
		if ((CCU_CAN_BMS_ADDR == gwcan.ps) || (CCU_CAN_CHARGER_ADDR == gwcan.ps))
		{
			//can_debug("Frame PS:0x%X, ", gwcan.ps);
			//can_debug("port:%d, %s", port, temp_str);	// 打印CAN接收内容
			return -10;
		}
		printf("\r\n\r\n地址错误  地址错误 地址错误  地址错误 地 地址错误 port=%d  gwcan.ps=%x qid=%d\r\n\r\n",port,gwcan.ps,qid);
		return -2;
	}

	qid=findexistaddr(port,gwcan.sa);
	if(qid<0)
	{
		printf("\r\n\r\n地址错误  地址错误 地址错误  地址错误 地 地址错误 port=%d  gwcan.sa=%x qid=%d\r\n\r\n",port,gwcan.sa,qid);
		return -3;
	}
//	else
//		printf("\r\n\r\n地址正确  地址正确 地址正确  地址正确 地址正确  地址正确 port=%d  gwcan.sa=%x\r\n\r\n",port,gwcan.sa);


//
//		if (gwcan.ps != TCU_CAN_ADDR || gwcan.sa != canaddr) {
//           printf("\r\n\r\n地址错误  地址错误 地址错误  地址错误 地址错误  地址错误\r\n\r\n");
//		return 2;
//		}

	memcpy(gwcan.pdata,pRxmsg->data,gwcan.lendata);
    return qid;
}
//
OS_TaskRet TaskTcuRecv1(void *arg)
{
    int len;
	CanMsg frdup;
	struct timeval tv;

	fd_set rset;
	msgtcu msgs;
	int ret;
	GW_Can gwcan;
	u8 port=1;
	int qid=0;

//	while(initcansocket(port,&socket_can[port])!=0)
//	{
//		can_debug("初始化失败");//获得枪的充电状态
//		sleep(1);
//	}

	//can_debug("CAN初始化成功  qmegid[%d]=%d",port,g_qmegid[port]);
//	msgs.msgtype=2;
//
//   if(msgsnd(g_qmegid[port], &msgs, sizeof(msgtcu), IPC_NOWAIT) != -1)
//	   	{
//	   		can_debug("发送can连接成功消息成功  qmegid=%d",g_qmegid[port]);
//	   	}
   //sleep(4);


	while (1) {
		//	sleep(1);
			tv.tv_sec = 0;
			tv.tv_usec =50000;
			FD_ZERO(&rset);
			FD_SET(socket_can[port], &rset);
			ret = select(socket_can[port]+1, &rset, NULL, NULL, &tv);
			if (ret == 0) {
		 //   	myerr("main 2 candll select time out       gunno=1");
				continue;
			}
            len= sizeof(CanMsg);
			ret = read(socket_can[port], &frdup,len);
			if (ret < len) {
	     		myerr("read failed");
				continue;
			}
			msgs.msgtype=1;
			qid=analyseCan(port,&frdup,gwcan);
			if(qid<=0)
			{
				if (qid != -10)
					ui_debug("222是否是这里出了问题！！！！！！！qid=%d",qid);
				continue;
			}
//			else
//			{
//				if(gwcan.pf ==0x41)
//				{
//					ui_debug1("接收到一帧心跳 接收到一帧心跳  接收到一帧心跳  port=1 ");
//				}
//				else
//					ui_debug1("接收到一帧其他帧  port=1 ");
//
////				if(gwcan.pf ==0x20)
////				{
////					printf("\r\n\r\n\r\n\r\n收到pf[1]=20 !！！！！！！！！！！！！！！！！！！！！！！！！！！！！！\r\n\r\n");
////				}
////				if(gwcan.pf ==0x02 || gwcan.pf ==0x04 || gwcan.pf ==0x11 || gwcan.pf ==0x13)
////						msgs.msgtype=4;
//			}
		    memcpy(msgs.pmsg,(char*)&gwcan,sizeof(GW_Can));
		    if (msgsnd(qid, &msgs, sizeof(msgtcu), IPC_NOWAIT) != -1)//can_recv_form_tcu
		    {
	    	//ui_debug1("发送到CANDLL port=%d qid=%dsucc succ succ succ !!!!!!!\r\n",port,qid);
		    }
		    else
		    {
		    	printf("发送到CANDLL err err err  port=%d qid=%d!!!!!!!\r\n",port,qid);
		//    	usleep(1000);
		    }

		}
    return NULL;
}


OS_TaskRet TaskTcuRecv(void *arg)
{//tt000000000出现can故障
    int len;
	CanMsg frdup;
	struct timeval tv;
	int qid=0;

	fd_set rset;
	msgtcu msgs;
	int ret;
	GW_Can gwcan;
	u8 port=0;
	initTask_Timer_main();
//	while(initcansocket(port,&socket_can[port])!=0)
//	{
//		can_debug("初始化失败");//获得枪的充电状态
//		sleep(1);
//	}

//	sleep(4);
	//can_debug("CAN初始化成功  qmegid[%d]=%d",port,g_qmegid[port]);
//	msgs.msgtype=2;

//   if(msgsnd(g_qmegid[port], &msgs, sizeof(msgtcu), IPC_NOWAIT) != -1)
//	   	{
//	   		can_debug("发送can连接成功消息成功  qmegid=%d",g_qmegid[port]);
//	   	}
//   else
//	   can_debug("发送can连接成功消息失败  qmegid=%d",g_qmegid[port]);

	while (1) {
		//	sleep(1);
			tv.tv_sec = 0;
			tv.tv_usec = 50000;
			FD_ZERO(&rset);
			FD_SET(socket_can[port], &rset);
			ret = select(socket_can[port]+1, &rset, NULL, NULL, &tv);
			if (ret == 0) {
		  //  	myerr("main 2 candll select time out5  gunno=0");
				continue;
			}
            len= sizeof(CanMsg);
			ret = read(socket_can[port], &frdup,len);
			if (ret < len) {
	//			myerr("read failed");
				continue;
			}
			msgs.msgtype=1;
			qid=analyseCan(port,&frdup,gwcan);
			if(qid<0)
			{
				if (qid != -10)
					ui_debug("111是否是这里出了问题！！！！！！！");
				continue;
			}
			else
			{
//				if(gwcan.pf ==0x41)
//				{
//					ui_debug1("接收到一帧心跳 接收到一帧心跳  接收到一帧心跳  gunid=0 ");
//				}

//				if(gwcan.pf ==0x20)
//				{
//					printf("\r\n\r\n\r\n\r\n收到pf[0]=20 !！！！！！！！！！！！！！！！！！！！！！！！！！！！！！\r\n\r\n");
//				}
//				if(gwcan.pf ==0x02 || gwcan.pf ==0x04 || gwcan.pf ==0x11 || gwcan.pf ==0x13)
//						msgs.msgtype=4;
			}
		    memcpy(msgs.pmsg,(char*)&gwcan,sizeof(GW_Can));
		    if (msgsnd(qid, &msgs, sizeof(msgtcu), IPC_NOWAIT) != -1)//can_recv_form_tcu
		    {
		//    	can_debug("发送到CANDLL port=%d qid=%dsucc succ succ succ !!!!!!!\r\n",port,qid);
		    }
		    else
		    {
		    	printf("发送到CANDLL err err err  port=%d qid=%d!!!!!!!\r\n",port,qid);
//	         	usleep(1000);
		    }
		}
    return NULL;
}

void initTaskTcuRecv(void)
{
	u8 cannum=pconfig->cannum;
	key_t key=0;
	int i;
	canlink *note;
	canlink *ptail[]={NULL,NULL};//向控制器发送心跳包

  	while (init_can(0, CAN_SAMPLATE) != 0)
  	{
  		can_debug("can0 初始化失败");//获得枪的充电状态
  		sleep(1);
  	}

   	while (init_can(1, CAN_SAMPLATE) != 0)
   	{
   		can_debug("can1 初始化失败");//获得枪的充电状态
   		sleep(1);
   	}

   	while(initcansocket(0,&socket_can[0])!=0)
   	{
   		can_debug("初始化失败");//获得枪的充电状态
   		sleep(1);
   	}
    
	while(initcansocket(1,&socket_can[1])!=0)
	{
		can_debug("初始化失败");//获得枪的充电状态
		sleep(1);
	}
    
	for (i=0; i<pconfig->gunnum; i++)
	{

		if (findexistaddr(gun_can_info_tab[i].port,gun_can_info_tab[i].cha_addr) >= 0)
		{
			continue;
		}

		note=(canlink*) new canlink;
		key=0;
		note->qid=-1;
		note->pNext=NULL;
		note->addr=gun_can_info_tab[i].cha_addr;
		note->qid =os_create_msgqueue(&key,1);
        printf("\r\n gun[%d]- port:0x%x - addr:0x%x- qid:0x%x", i, gun_can_info_tab[i].port, note->addr, note->qid);

		note->pNext=NULL;
		if (gun_can_info_tab[i].port == 0)
		{
			if (g_pcan[0] == NULL)
			{
		     	g_pcan[0]=note;
		    	ptail[0]=note;
			}
			else
			{
				ptail[0]->pNext=note;
				ptail[0]=note;
			}
		}
		else
		{

			if(g_pcan[1] == NULL)//uu
			{
		     	g_pcan[1]=note;
		    	ptail[1]=note;
			}
			else
			{
				ptail[1]->pNext=note;
				ptail[1]=note;
			}
		}
	}
    initcan_main(*pconfig);

	Info_TaskTcuRecv[0].Prio = 0;
    Info_TaskTcuRecv[0].Stk = NULL;
	Info_TaskTcuRecv[0].Stk_Size = 0;
	os_create_task(TaskTcuRecv, NULL, &Info_TaskTcuRecv[0]);
	if(cannum==2 && pconfig->gunnum>=2)
	{
		Info_TaskTcuRecv[1].Prio = 0;
		Info_TaskTcuRecv[1].Stk = NULL;
		Info_TaskTcuRecv[1].Stk_Size = 0;
		os_create_task(TaskTcuRecv1, NULL, &Info_TaskTcuRecv[1]);
	 }
}

